// ================================================================================
// 告警日志逻辑实现
// ================================================================================

package alertLog

import (
	"context"
	"devops-super/api"
	"devops-super/api/alerts/v1"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"devops-super/utility/util/arrayUtil"
	"errors"
	"github.com/gogf/gf/v2/os/gtime"
	"time"
)

type sAlertLog struct{}

var cols = dao.AlertLogDemo.Columns()

func init() {
	service.RegisterAlertLog(New())
}

func New() *sAlertLog {
	return &sAlertLog{}
}

// Add 添加告警日志
func (*sAlertLog) Add(ctx context.Context, in *entity.AlertLogDemo) (err error) {
	// 设置默认值
	if in.HandleStatus == 0 {
		in.HandleStatus = 0 // 未处理
	}
	in.CreatedAt = gtime.Now()
	in.UpdatedAt = gtime.Now()

	_, err = dao.AlertLogDemo.Ctx(ctx).Insert(in)
	return
}

// Upt 更新告警日志
func (*sAlertLog) Upt(ctx context.Context, in *entity.AlertLogDemo) (err error) {
	// 验证日志是否存在
	exist, err := dao.AlertLogDemo.Ctx(ctx).WherePri(in.Id).Count()
	if err != nil {
		return err
	}
	if exist == 0 {
		return errors.New("告警日志不存在")
	}

	// 更新时间
	in.UpdatedAt = gtime.Now()

	_, err = dao.AlertLogDemo.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
	return
}

// GetPageLst 分页获取告警日志列表
func (*sAlertLog) GetPageLst(ctx context.Context, req *v1.AlertLogGetPageLstReq) (out *api.PageLstRes[*mymodel.AlertLogResponse], err error) {
	out = &api.PageLstRes[*mymodel.AlertLogResponse]{}
	m := dao.AlertLogDemo.Ctx(ctx).Safe(true)

	// 告警场景筛选
	if req.SceneId > 0 {
		m = m.Where(cols.SceneId, req.SceneId)
	}

	// 等级筛选
	if req.Level > 0 {
		m = m.Where(cols.Level, req.Level)
	}

	// 绑定范围筛选
	if req.BindTo > 0 {
		m = m.Where(cols.BindTo, req.BindTo)
	}

	// 绑定ID筛选
	if req.BindId != "" {
		m = m.Where(cols.BindId, req.BindId)
	}

	// 部门筛选
	if req.DeptId > 0 {
		m = m.Where(cols.DeptId, req.DeptId)
	}

	// 处理状态筛选
	if req.HandleStatus >= 0 {
		m = m.Where(cols.HandleStatus, req.HandleStatus)
	}

	// 按时间范围筛选
	if req.TimeRange != nil && len(req.TimeRange) == 2 {
		// 新增时间转换逻辑
		startTime, err := time.Parse(time.RFC3339, req.TimeRange[0])
		if err != nil {
			return nil, errors.New("开始时间格式错误")
		}
		endTime, err := time.Parse(time.RFC3339, req.TimeRange[1])
		if err != nil {
			return nil, errors.New("结束时间格式错误")
		}
		timeLayout := "2006-01-02 15:04:05"
		timeStr0 := startTime.Local().Format(timeLayout)
		timeStr1 := endTime.Local().Format(timeLayout)
		m = m.WhereBetween(cols.CreatedAt, timeStr0, timeStr1)
	}

	// 分页查询原始实体
	var entities []*entity.AlertLogDemo
	if err = m.Offset(req.Offset()).Limit(req.Limit()).OrderDesc(cols.CreatedAt).ScanAndCount(&entities, &out.Total, false); err != nil {
		return
	}

	deptIds := make([]int64, 0)
	sceneIds := make([]int64, 0)
	for _, item := range entities {
		if !arrayUtil.IsExistsItem(item.DeptId, deptIds) {
			deptIds = append(deptIds, item.DeptId)
		}
		if !arrayUtil.IsExistsItem(item.SceneId, sceneIds) {
			sceneIds = append(sceneIds, item.SceneId)
		}
	}

	var deptResults []*entity.Dept
	_ = dao.Dept.Ctx(ctx).WhereIn(dao.Dept.Columns().Id, deptIds).Scan(&deptResults)
	var sceneResults []*entity.AlertScene
	_ = dao.AlertScene.Ctx(ctx).WhereIn(dao.AlertScene.Columns().Id, sceneIds).Scan(&sceneResults)

	// 转换为响应模型
	out.List = make([]*mymodel.AlertLogResponse, len(entities))
	for i, e := range entities {
		deptName := ""
		for _, item := range deptResults {
			if int64(item.Id) == e.DeptId {
				deptName = item.Name
			}
		}
		sceneName := ""
		for _, item := range sceneResults {
			if int64(item.Id) == e.SceneId {
				sceneName = item.Name
			}
		}
		// 基础字段映射
		out.List[i] = &mymodel.AlertLogResponse{
			Id:           e.Id,
			SceneId:      e.SceneId,
			Level:        e.Level,
			BindTo:       e.BindTo,
			BindId:       e.BindId,
			DeptId:       e.DeptId,
			Detail:       e.Detail,
			Sampletime:   e.Sampletime,
			HandleStatus: e.HandleStatus,
			HandleTime:   e.HandleTime,
			HandRemark:   e.HandRemark,
			CreatedAt:    e.CreatedAt,
			UpdatedAt:    e.UpdatedAt,
			DeptName:     deptName,
			SceneName:    sceneName,
		}
	}
	return
}

// UptStatus 更新告警日志状态
func (*sAlertLog) UptStatus(ctx context.Context, id int64, status int) (err error) {
	// 验证日志是否存在
	exist, err := dao.AlertLogDemo.Ctx(ctx).WherePri(id).Count()
	if err != nil {
		return err
	}
	if exist == 0 {
		return errors.New("告警日志不存在")
	}

	// 更新状态
	_, err = dao.AlertLogDemo.Ctx(ctx).WherePri(id).Data(cols.HandleStatus, status).Update()
	return
}

// Del 删除告警日志
func (*sAlertLog) Del(ctx context.Context, id int64) (err error) {
	// 验证日志是否存在
	exist, err := dao.AlertLogDemo.Ctx(ctx).WherePri(id).Count()
	if err != nil {
		return err
	}
	if exist == 0 {
		return errors.New("告警日志不存在")
	}

	_, err = dao.AlertLogDemo.Ctx(ctx).WherePri(id).Delete()
	return
}

// GetOne 获取单条告警日志
func (*sAlertLog) GetOne(ctx context.Context, id int64) (out *entity.AlertLogDemo, err error) {
	out = &entity.AlertLogDemo{}
	err = dao.AlertLogDemo.Ctx(ctx).WherePri(id).Scan(out)
	if err != nil {
		return nil, err
	}
	return
}

// GetOptions 获取告警日志选项
func (*sAlertLog) GetOptions(ctx context.Context, in *v1.AlertLogGetOptionsReq) (out *v1.AlertLogGetOptionsRes, err error) {
	out = new(v1.AlertLogGetOptionsRes)
	// 这里可以根据需要实现不同的选项获取逻辑
	// 例如获取处理状态选项、告警等级选项等

	// 默认返回处理状态选项
	out.Options = []*api.FormOptionsItem{
		{Value: 0, Label: "未处理"},
		{Value: 1, Label: "处理中"},
		{Value: 2, Label: "处理完成"},
	}
	return
}

// HandleLog 处理告警日志
func (*sAlertLog) HandleLog(ctx context.Context, id int64, handleStatus int, handRemark string) (err error) {
	// 验证日志是否存在
	exist, err := dao.AlertLogDemo.Ctx(ctx).WherePri(id).Count()
	if err != nil {
		return err
	}
	if exist == 0 {
		return errors.New("告警日志不存在")
	}

	// 准备更新数据
	updateData := map[string]interface{}{
		cols.HandleStatus: handleStatus,
		cols.HandRemark:   handRemark,
		cols.UpdatedAt:    gtime.Now(),
	}

	// 如果处理状态为1或2，设置处理时间
	if handleStatus == 1 || handleStatus == 2 {
		updateData[cols.HandleTime] = gtime.Now()
	}

	_, err = dao.AlertLogDemo.Ctx(ctx).WherePri(id).Data(updateData).Update()
	return
}

// BatchDel 批量删除告警日志
func (*sAlertLog) BatchDel(ctx context.Context, ids []int64) (err error) {
	if len(ids) == 0 {
		return errors.New("ID列表不能为空")
	}

	// 验证所有日志是否存在
	existCount, err := dao.AlertLogDemo.Ctx(ctx).Where(cols.Id+" IN (?)", ids).Count()
	if err != nil {
		return err
	}
	if existCount != int(len(ids)) {
		return errors.New("部分告警日志不存在")
	}

	_, err = dao.AlertLogDemo.Ctx(ctx).Where(cols.Id+" IN (?)", ids).Delete()
	return
}

// BatchHandle 批量处理告警日志
func (*sAlertLog) BatchHandle(ctx context.Context, ids []int64, handleStatus int, handRemark string) (err error) {
	if len(ids) == 0 {
		return errors.New("ID列表不能为空")
	}

	// 验证所有日志是否存在
	existCount, err := dao.AlertLogDemo.Ctx(ctx).Where(cols.Id+" IN (?)", ids).Count()
	if err != nil {
		return err
	}
	if existCount != int(len(ids)) {
		return errors.New("部分告警日志不存在")
	}

	// 准备更新数据
	updateData := map[string]interface{}{
		cols.HandleStatus: handleStatus,
		cols.HandRemark:   handRemark,
		cols.UpdatedAt:    gtime.Now(),
	}

	// 如果处理状态为1或2，设置处理时间
	if handleStatus == 1 || handleStatus == 2 {
		updateData[cols.HandleTime] = gtime.Now()
	}

	_, err = dao.AlertLogDemo.Ctx(ctx).Where(cols.Id+" IN (?)", ids).Data(updateData).Update()
	return
}
